<template>
  <view class="calendar-box">
    <view class="top">
      <view>
        <h4>已连续签到 <span> {{ checkinDays }} </span> 天</h4>
        <p v-if="isIntegral">今日获得+{{ integral }}积分</p>
      </view>
      <view class="rig">
        <span v-if="supplementary" @click="handleShiftSign">补签</span>
      </view>
    </view>
    <view class="calendar-content">
      <view class="month">
        <view class="month-nav prv" @click="navigateMonth(-1)">
          <span v-show="canNavigateToPreviousMonth">上月</span>
        </view>
        <view class="current-month">{{ year }}年{{ month }}月</view>
        <view class="month-nav next" @click="navigateMonth(1)">
          <span v-show="canNavigateToNextMonth">下月</span>
        </view>
        <picker v-if="checkDate" class="date-picker" mode="date" fields="month" @change="handleDateChange" />
      </view>
      <view class="week">
        <view :style="'color:' + (dayOfWeek === weekDay ? bgweek : '') + ';'" v-for="weekDay in weekArr" :key="weekDay">{{ weekDay }}</view>
      </view>
      <view class="day">
        <view 
          :class="[ 
            { 'checkday': !day.date }, 
            { 'choose': day.date === currentDate || day.isSigned } 
          ]"
          :style="'background:' + (day.date === currentDate || day.isSigned ? bgday : '') + ';'
          " v-for="(day, index) in dayList" :key="index"
          @click="handleSign(day, index)"
        >
          {{ day.day }}
          <view :class="[ 
            { 'circle': day.isSigned }, 
            { 'repair': day.day < today }, 
            { 'sign': day.day === today } 
          ]"></view>
        </view>
      </view>
    </view>
    <view class="sign-button-container">
      <button 
        :disabled="isCurrentMonth ? false : true" 
        :style="'background: ' + (isTodaySigned ? signin_but_bg : (isCurrentMonth ? bgday : signin_but_bg)) + ';'
        " @click="handleTodaySign"
      >
        签到
      </button>
    </view>
  </view>
</template>

<script>
  export default {
    name: 'youlanSignIn',
    props: {
      lang: {
        type: String,
        default: 'zh'
      },
      type: {
        type: String,
        default: 'calendar'
      },
      checkDate: {
        type: Boolean,
        default: false
      },
      bgweek: {
        type: String,
        default: '#FF8F22'
      },
      bgday: {
        type: String,
        default: '#FF8F22'
      },
      // 不能签到时的按钮颜色
      signin_but_bg: {
        type: String,
        default: '#909399'
      },
      supplementary: {
        type: Boolean,
        default: true
      },
      already: {
        type: Array,
        default: () => []
      },
      checkinDays: {
        type: [Number, String],
        default: 0
      },
      integral: {
        type: [Number, String],
        default: 0
      },
      isIntegral: {
        type: Boolean,
        default: false
      }
    },
    watch: {
      already: {
        handler() {
          this.updateSignedDays();
        },
        immediate: true,
        deep: true
      }
    },
    data() {
      const today = new Date();
      return {
        dayList: [], // 当前月每日列表
        currentDate: '', // 今天日期
        today: today.getDate(), // 当前日
        year: today.getFullYear(), // 当前年
        month: today.getMonth() + 1, // 当前月
        weekArr: ['日', '一', '二', '三', '四', '五', '六'], // 每周
        leadingEmptyDays: 0, // 前方空白天数数量
        isCurrentMonth: today.getMonth() + 1 === today.getMonth() + 1,
        canNavigateToPreviousMonth: true,
        canNavigateToNextMonth: true,
        // 判断今天是否已经签到
        isTodaySigned: false,
        // 今天周几的索引
        dayOfWeek: ''
      }
    },
    computed: {
      // 计算属性：格式化当前日期为字符串
      formattedToday() {
        const today = new Date();
        return `${today.getFullYear()}-${this.formatNum(today.getMonth() + 1)}-${this.formatNum(today.getDate())}`;
      }
    },
    mounted() {
      // 初始化日期
      this.initializeDate();
      // 设置语言
      this.setLanguage();
    },
    methods: {
      // 初始化日期相关数据
      initializeDate() {
        const today = new Date();
        // 设置今天的日期字符串
        this.currentDate = this.formattedToday;
        // 设置今天周几
        this.dayOfWeek = this.weekArr[today.getDay()];
        // 初始化日历数据
        this.generateCalendarDays();
      },
      
      // 设置语言
      setLanguage() {
        if (this.lang !== 'zh') {
          this.weekArr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
          this.dayOfWeek = this.weekArr[new Date().getDay()];
        }
      },
      
      // 生成日历数据
      generateCalendarDays() {
        this.dayList = [];
        // 当前月总天数
        const totalDays = new Date(this.year, this.month, 0).getDate();
        // 遍历总天数将日期逐个添加至数组
        for (let i = 1; i <= totalDays; i++) {
          // 得到需补充天数
          const dayOfWeek = (new Date(this.year, this.month - 1, i)).getDay();
          // 补充前面空白日期
          if (i === 1 && dayOfWeek !== 0) {
            this.addLeadingEmptyDays(dayOfWeek);
          }
          // 添加本月日期
          const dateStr = `${this.year}-${this.formatNum(this.month)}-${this.formatNum(i)}`;
          this.dayList.push({
            date: dateStr,
            day: i,
            isSigned: false
          });
          // 补充后面空白日期
          if (i === totalDays && dayOfWeek !== 6) {
            this.addTrailingEmptyDays(dayOfWeek);
          }
        }
        // 更新已签到状态
        this.updateSignedDays();
        // 更新导航按钮状态
        this.updateNavigationButtons();
      },
      
      // 更新已签到的日期状态
      updateSignedDays() {
        for (let i = 0; i < this.dayList.length; i++) {
          const day = this.dayList[i];
          if (!day.date) continue;
          
          const dateTime = new Date(day.date).getTime();
          const isSigned = this.already.includes(dateTime);
          
          this.$set(this.dayList[i], 'isSigned', isSigned);
          
          // 检查今天是否已经签到
          if (day.date === this.currentDate) {
            this.isTodaySigned = isSigned;
          }
        }
      },
      
      // 补充前面空白日期
      addLeadingEmptyDays(count) {
        this.leadingEmptyDays = count;
        const lastMonth = new Date(this.year, this.month - 1, 0);
        const lastMonthTotalDays = lastMonth.getDate();
        
        for (let i = 0; i < count; i++) {
          const day = lastMonthTotalDays - (count - i) + 1;
          this.dayList.push({
            date: '',
            day: day,
            isSigned: false
          });
        }
      },
      
      // 补充后面空白日期
      addTrailingEmptyDays(currentDayOfWeek) {
        const daysToAdd = 6 - currentDayOfWeek;
        for (let i = 0; i < daysToAdd; i++) {
          this.dayList.push({
            date: '',
            day: i + 1,
            isSigned: false
          });
        }
      },
      
      // 格式化日期位数
      formatNum(num) {
        return num < 10 ? `0${num}` : num;
      },
      
      // 导航到上个月或下个月
      navigateMonth(direction) {
        if (direction === -1 && !this.canNavigateToPreviousMonth) return;
        if (direction === 1 && !this.canNavigateToNextMonth) return;
        
        if (direction === -1) {
          // 上个月
          if (this.month === 1) {
            this.year -= 1;
            this.month = 12;
          } else {
            this.month -= 1;
          }
        } else {
          // 下个月
          if (this.month === 12) {
            this.year += 1;
            this.month = 1;
          } else {
            this.month += 1;
          }
        }
        
        this.generateCalendarDays();
      },
      
      // 更新导航按钮状态
      updateNavigationButtons() {
        const today = new Date();
        const currentDate = new Date(this.year, this.month - 1, 1);
        
        // 不允许查看未来月份
        const maxAllowedMonth = new Date(today.getFullYear(), today.getMonth() + 2, 1);
        this.canNavigateToNextMonth = currentDate < maxAllowedMonth;
        
        // 不允许查看超过当前年份的过往月份
        const minAllowedMonth = new Date(today.getFullYear(), 0, 1);
        this.canNavigateToPreviousMonth = currentDate >= minAllowedMonth;
        
        // 检查是否是当前月份
        this.isCurrentMonth = this.month === (today.getMonth() + 1) && this.year === today.getFullYear();
      },
      
      // 处理日期选择
      handleDateChange(e) {
        const [year, month] = e.detail.value.split('-').map(Number);
        this.year = year;
        this.month = month;
        this.generateCalendarDays();
      },
      
      // 处理补签触发
      handleShiftSign() {
        this.$emit('shift');
      },
      
      // 处理今日签到
      handleTodaySign() {
        // 今天日期加上前方空白日期数量
        const todayIndex = this.leadingEmptyDays + this.today - 1;
        
        if (todayIndex >= 0 && todayIndex < this.dayList.length) {
          const todayData = this.dayList[todayIndex];
          
          if (todayData.isSigned) {
            // 已经签到后不能签到
            uni.showToast({
              title: '今日已签到',
              icon: 'none'
            });
            return;
          }
          
          // 更新状态并触发事件
          this.$set(this.dayList[todayIndex], 'isSigned', true);
          this.$emit('change', todayData.date);
          this.isTodaySigned = true;
          
          uni.showToast({
            title: '签到成功',
            icon: 'success'
          });
        }
      },
      
      // 处理日期点击（补签或签到）
      handleSign(dayData, index) {
        // 如果是日历模式或没有日期，不处理点击
        if (this.type === 'calendar' || !dayData.date) return;
        
        // 获取当前月份
        const currentMonth = new Date().getMonth() + 1;
        const targetMonth = parseInt(dayData.date.split('-')[1]);
        
        // 限制只能操作本月日期
        if (currentMonth !== targetMonth) return;
        
        // 只有日期小于今天才允许点击（补签）
        if (dayData.day < this.today) {
          // 开启已签到提醒
          if (dayData.isSigned) {
            uni.showToast({
              title: '已签到',
              icon: 'none'
            });
          } else {
            // 检查是否允许补签
            if (dayData.day < this.today && !this.supplementary) {
              return;
            }
            
            // 执行补签
            this.$set(this.dayList[index], 'isSigned', true);
            this.$emit('change', dayData.date);
            
            uni.showToast({
              title: '补签成功',
              icon: 'success'
            });
          }
        }
      }
    }
  }
</script>

<style scoped>
  .calendar-box {
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  
  .calendar-content {
    width: 100%;
    padding: 20rpx 40rpx;
    box-sizing: border-box;
    background-color: #FFFFFF;
    border-radius: 25rpx;
  }
  
  .calendar-box,
  .month,
  .week,
  .day {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  
  .month,
  .week,
  .day {
    width: 100%;
  }
  
  .month {
    margin: 30rpx 0;
    position: relative;
  }
  
  .current-month {
    font-weight: 600;
    font-size: 32rpx;
  }
  
  .month-nav {
    min-width: 60rpx;
    text-align: center;
  }
  
  .date-picker {
    width: 160rpx;
    height: 40rpx;
    position: absolute;
    top: 20rpx;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  
  .day {
    flex-wrap: wrap;
  }
  
  .week>view,
  .day>view {
    width: 70rpx;
    height: 70rpx;
    margin: 10rpx;
    text-align: center;
    position: relative;
    line-height: 70rpx;
    font-size: 28rpx;
    transition: all 0.3s ease;
  }
  
  .week>view {
    font-weight: 600;
    font-size: 26rpx;
  }
  
  .checkday {
    color: #999;
  }
  
  .choose {
    color: #FFFFFF;
    border-radius: 50%;
  }
  
  .circle {
    width: 10rpx;
    height: 10rpx;
    border-radius: 50%;
    position: absolute;
    bottom: 10%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  
  .sign {
    background-color: #FFF;
  }
  
  .repair {
    background-color: #FFF;
  }
  
  .sign-button-container {
    display: flex;
    flex: 1;
    margin-top: 80rpx;
    justify-content: center;
  }
  
  .sign-button-container button {
    width: 650rpx;
    height: 80rpx;
    line-height: 80rpx;
    border-radius: 30rpx;
    border: 1px solid transparent;
    outline: none;
    color: #FFFFFF;
    font-size: 32rpx;
    transition: all 0.3s ease;
  }
  
  .sign-button-container button:active:not([disabled]) {
    transform: scale(0.98);
  }
  
  uni-button:after {
    border: none;
  }
  
  .top {
    display: flex;
    width: 100%;
    justify-content: space-between;
    padding: 30rpx;
    box-sizing: border-box;
    background-color: #FFFFFF;
    border-radius: 20rpx;
    margin-bottom: 16rpx;
    align-items: center;
    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
  }
  
  .top h4 {
    font-weight: 600;
    font-size: 36rpx;
    line-height: 50rpx;
    margin: 0;
  }
  
  .top h4 span {
    color: #FF871E;
    margin: 0 10rpx;
    font-size: 32rpx;
  }
  
  .top p {
    font-style: normal;
    font-weight: normal;
    font-size: 28rpx;
    line-height: 40rpx;
    color: #FF871E;
    margin: 0;
  }
  
  .rig span {
    font-style: normal;
    font-weight: normal;
    font-size: 24rpx;
    line-height: 48rpx;
    color: #FF871E;
    border: 1px solid #FF871E;
    padding: 10rpx 20rpx;
    border-radius: 32rpx;
    transition: all 0.3s ease;
  }
  
  .rig span:active {
    background-color: #FF871E;
    color: #FFFFFF;
  }
</style>
